/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       single_use_object.h

	$Header: /game/single_use_object.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "single_use_object.h"

#include "adventure_frame.h"
#include "adventure_map.h"
#include "army.h"
#include "basic_dialog.h"
#include "external_string.h"
#include "game_replace_keywords.h"
#include "hero.h"
#include "mouse_event.h"
#include "player.h"
#include "simple_dialog.h"

extern t_external_string const k_text_dead_heroes_ineligible( "dead_heroes_ineligible.misc" );

void t_single_use_object::set_use_id( t_adventure_map& map )
{
	if (m_single_use_id < 0)
		m_single_use_id = map.get_new_single_use_id();
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
void t_single_use_object::initialize( t_adventure_map& map )
{
	set_use_id( map );
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
std::string t_single_use_object::add_icons( t_basic_dialog* dialog, std::string const& text, std::vector<t_hero*> const& heroes )
{
	return text;
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
extern t_external_string const k_text_and;

void t_single_use_object::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                                    t_direction direction, t_adventure_frame* frame )
{
	t_creature_array& creatures = army->get_creatures();

	int                  i;
	t_hero*              hero;
	std::vector<t_hero*> heroes;
	bool				 any_heroes = false;
	bool				 all_heroes_ineligible = false;
	bool				 dead_heroes = true;

    all_heroes_ineligible = are_all_heroes_ineligible( army );

	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero = creatures[i].get_hero();
		if (hero == 0)
			continue;

		any_heroes = true;

		if (hero->is_dead())
			continue;
	    dead_heroes = false;

		if (hero->has_visited( *this ))
			continue;

		visit( hero );
		heroes.push_back( hero );
		hero->set_visited( *this );
	}
	if (!army->get_owner()->is_computer())
	{
		std::string text;

		if (all_heroes_ineligible)
		{
			ok_dialog( get_text("heroes_full"), get_dialog_bottom( point ) );
			return;
		}
        // No heroes.
		if (!any_heroes)
		{
			ok_dialog( get_text("no_heroes"), get_dialog_bottom( point ) );
			return;
		}
        // Heroes all dead.
		if (dead_heroes)
        {
		    text = get_text("heroes_dead");
            if (text == "")
                text = k_text_dead_heroes_ineligible;
			ok_dialog( text, get_dialog_bottom( point ) );
			return;
        }
		if (heroes.size() == 0)
		{
			ok_dialog( get_text( "visited" ), get_dialog_bottom( point ) );
			return;
		}

		if (heroes.size() == 1)
		{
			text = replace_keywords( get_text( "one_hero" ), heroes.front() );
		}
		else
		{
			text = replace_keywords( get_text( "several_heroes" ), heroes );
		}

		t_basic_dialog* dialog;

		// initialize dialog
		dialog = new t_basic_dialog;
		text = add_icons( dialog, text, heroes );
		dialog->set_text( text );
		dialog->add_ok_button();
		dialog->set_title( get_name() );
		dialog->open( get_dialog_bottom( point ), true, k_align_bottom );
		dialog->run_modal();
	}
	for (i = 0; i < heroes.size(); i++)
	{
		heroes[i]->check_level( *get_map(), frame, army->get_owner() );
	}
}

bool t_single_use_object::are_all_heroes_ineligible( t_army* army ) const
{
    return false;
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
bool t_single_use_object::visited() const
{
	int                 i;
	t_hero*             hero;
	t_adventure_frame*  adventure_frame = get_adventure_frame();
	t_army*				army = adventure_frame->get_selected_army();
	bool				result = false;

	if (army == 0)
		return false;

	t_creature_array& creatures = army->get_creatures();

	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero = creatures[i].get_hero();
		if (hero == 0)
			continue;

		if (hero->has_visited( *this ))
			result = true;
	}
	return result;
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
extern t_external_string const k_text_visited( "visited.object" );

std::string t_single_use_object::get_balloon_help() const
{
	std::string result = t_stationary_adventure_object::get_name();

	if (visited())
	{
		result += " ";
		result += k_text_visited;
	}
	return result;
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
void t_single_use_object::right_click( t_mouse_event const& event,
		                               t_adventure_frame* adventure_frame )
{
	std::string help_text;

	if (visited())
		help_text = get_text( "help_visited" );
	else
		help_text = get_text( "help" );
	show_popup_text( help_text, event.screen_point );
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
bool t_single_use_object::write( std::streambuf& stream ) const
{
	put<int>( stream, m_single_use_id );
	return true;
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
bool t_single_use_object::read( std::streambuf&					 stream, 
							    t_qualified_adv_object_type const& type,
							    int								 version ) 
{
	m_single_use_id = get<int>( stream );
	return true;
}

// -------------------------------------------------------------
// place on map and get a single use id if neccessary
// -------------------------------------------------------------
void t_single_use_object::place( t_adventure_map& map, t_adv_map_point const& point )
{
	set_use_id( map );
	t_stationary_adventure_object::place( map, point );
}

